﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel;

namespace Dycox.ComponentModel
{
    public class StateContract
    {
        public StateContract()
            : this(new StateObject())
        {

        }

        public StateContract(StateObject state)
        {
            _state = state;
        }

        private StateObject _state;

        [Browsable(false)]
        public StateObject State
        {
            get { return _state; }
        }

        public virtual T GetValue<T>(string name)
        {
            return State.GetValue<T>(name);
        }

        public virtual void SetValue(string name, object value)
        {
            State[name] = value;
        }

        [OnSerializing]
        private void OnSerializingValues(StreamingContext context)
        {
            _serializingStatus = SerializationStatus.Serializing;
            this.OnSerializing(context);
        }

        protected virtual void OnSerializing(StreamingContext context)
        {
        }

        [OnSerialized]
        private void OnSerializedValues(StreamingContext context)
        {
            this.OnSerialized(context);
            _serializingStatus = SerializationStatus.None;
        }

        protected virtual void OnSerialized(StreamingContext context)
        {
        }

        [OnDeserializing]
        private void OnDeserializingValues(StreamingContext context)
        {
            _serializingStatus = SerializationStatus.Deserializing;
            this.OnDeserializing(context);
        }

        protected virtual void OnDeserializing(StreamingContext context)
        {
        }

        [OnDeserialized]
        private void OnDeserializedValues(StreamingContext context)
        {
            this.OnDeserialized(context);
            _serializingStatus = SerializationStatus.None;
        }

        protected virtual void OnDeserialized(StreamingContext context)
        {
        }

        public string ToJson()
        {
            return StateObject.ToJson(this);
        }

        public static T FromJson<T>(string jsonText)
            where T : StateContract
        {
            return StateObject.FromJson<T>(jsonText);
        }

        public virtual void Validate(MessageSet msgSet)
        {
        }

        public void Validate()
        {
            MessageSet msgSet = new MessageSet();
            Validate(msgSet);
            if (!msgSet.Success)
                throw new InvalidOperationException(msgSet.ToString());
        }

        private SerializationStatus _serializingStatus;

        public SerializationStatus SerializingStatus
        {
            get { return _serializingStatus; }
        }

    }
}
